#ifndef _USB_H_
#define _USB_H_

#include "core/include/types.h"

/* --- usb data structure */
#define USB_FULLSPEED				0x01
#define USB_LOWSPEED				0x02

/* Device Request */
/** bmRequestType **/
#define bmDATA_OUT				0x00
#define bmDATA_IN				(0x01 << 7)
#define bmTYPE_TYPICAL			0x00
#define bmTYPE_CLASS			(0x01 << 5)
#define bmTYPE_VENDER			(0x02 << 5)
#define bmTYPE_RESERVED			(0x03 << 5)
#define bmRECEIVER_DEVICE		0x00
#define bmRECEIVER_INTERFACE	0x01
#define bmRECEIVER_ENDPOINT		0x02
#define bmRECEIVER_OTHERS		0x03

/** bRequeat **/
#define CREAR_FEATURE					1
#define GET_CONFIGURATION				8
#define GET_DESCRIPTOR					6
#define GET_INTERFACE					10
#define GET_STATUS						0
#define SET_ADDRESS						5
#define SET_CONFIGURATION				9
#define SET_DESCRIPTOR					7
#define SET_FEATURE						3
#define SET_INRERFACE					11
#define SYSCH_FRAME						12


/* Descriptor Name */
#define DEVICE							(1<<8)
#define CONFIGURATION					(2<<8)
#define XSTRING							(3<<8)
#define INTERFACE						(4<<8)
#define ENDPOINT						(5<<8)
#define HID								(0x21<<8)
#define HIDREPORT						(0x22<<8)
#define HIDPHYSICAL						(0x23<<8)


/* Descriptors */
typedef struct
{
	unsigned char 	bLength;
	unsigned char 	bDescriptor;
	unsigned short	bcdUSB;
	unsigned char 	bDeviceClass;
	unsigned char	bDeviceSubClass;
	unsigned char	bDeviceProtocol;
	unsigned char	bMaxPacketSize0;
	unsigned short	idVendor;
	unsigned short	idProduct;
	unsigned short	bcdDevice;
	unsigned char	iManufacturer;
	unsigned char	iProduct;
	unsigned char	iSerialNumber;
	unsigned char	bNumConfigurations;
} USB_DEVICE_DESCROPTOR;

typedef struct
{
	BYTE bLength;
	BYTE bDescriptor;
	WORD wTotalLength;
	BYTE bNumInterfaces;
	BYTE ConfigurationValue;
	BYTE iConfiguration;
	BYTE bmAttributes;
	BYTE bMaxPower;
} USB_CONFIGURATION_DESCRIPTOR;


/* --- USB Request Packet ---- */
typedef struct
{
	unsigned char	bmRequestType;
	unsigned char	bRequest;
	unsigned short	wValue;
	unsigned short	wIndex;
	unsigned short	wLength;
} USB_REQUEST;


/* --- USB Descriptor package --- */
typedef struct t_USB_EP
{
	BYTE bDesc;
	BYTE bAdr;
	BYTE bDirection;
	BYTE bType;
	WORD payload;
	BYTE bInterval;
} USB_EP;

typedef struct t_USB_DT
{
	BYTE bDesc;
	BYTE bType;
	WORD wSize;
} USB_DT;


typedef struct t_USB_INTERFACE
{
	BYTE bDesc;
	BYTE bIfIndex;
	BYTE bNumEP;
	USB_EP *EP;
	USB_DT *DATA;
} USB_IF;

typedef struct t_USB_CFG
{
	BYTE bDesc;
	BYTE bCfgIndex;
	BYTE bCfgValue;
	BYTE bNumIF;
	USB_IF *IF;
} USB_CFG;

typedef struct t_USB_DEV
{
	BYTE bClass;
	BYTE bSubClass;
	BYTE bEP0Payload;

	BYTE adr;
	BYTE speed;

	BYTE bNumCFG;
	USB_CFG *CFG;
} USB_DEV;


/* --- usb host driver --- */
BOOL USB_Enumration(USB_DEV *dev);
BYTE USB_deviceCheck(void);

BYTE USB_ControlTransport(BYTE speed, BYTE usbAdr, BYTE EPx, USB_REQUEST *setupPacket, BYTE *buf);
BYTE USB_IN_transaction  (BYTE speed, BYTE usbAdr, BYTE EPx, BYTE *buf, WORD len);
BYTE USB_OUT_transaction (BYTE speed, BYTE usbAdr, BYTE EPx, BYTE *buf, WORD len);

BYTE USB_getDescriptor(   DWORD speed, BYTE usbAdr, WORD descType, BYTE *buf, WORD len);
BYTE USB_setConfiguration(DWORD speed, WORD usbAdr, WORD cfgIndex);

void showDevDsc(USB_DEV *dev);


/* --- USB handling process --- */


#endif/*_USB_H_*/
